package ursaminor.lazywork.common.util;

import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;


/**
 * 字符串处理工具类
 * 
 * @author Zhou Deming
 */
public final class StringUtils {

	/**
	 * Trim a string. Removes leading and trailing blanks. If the resulting
	 * string is empty, normalizes the string to an null string.
	 * 
	 * @param value
	 *            the string to trim
	 * @return the trimmed string, or null if the string is empty
	 */
	public static String trimString(String value) {
		if (value == null) return null;
		value = value.trim();
		if (value.length() == 0) return null;
		return value;
	}

	/**
	 * Convert an integer to an HTML RGB value. The result is of the form
	 * #hhhhhh. The input rgb integer value will be clipped into the range 0 ~
	 * 0xFFFFFF
	 * 
	 * @param rgb
	 *            the integer RGB value
	 * @return the value as an HTML RGB string
	 */
	public static String toRgbText(int rgb) {
		// clip input value.
		if (rgb > 0xFFFFFF)
			rgb = 0xFFFFFF;
		if (rgb < 0)
			rgb = 0;
		String str = "000000" + Integer.toHexString(rgb); //$NON-NLS-1$ 
		return "#" + str.substring(str.length() - 6); //$NON-NLS-1$ 
	}

	/**
	 * Check if the locale string is a valid locale format, with the language,
	 * country and variant separated by underbars.
	 * <p>
	 * The language argument is a valid <STRONG>ISO Language Code. </STRONG>.
	 * These codes are the lower-case, two-letter codes.
	 * <p>
	 * The country argument is a valid <STRONG>ISO Country Code. </STRONG> These
	 * codes are the upper-case, two-letter codes.
	 * <p>
	 * If the language is missing, the string should begin with an underbar.
	 * (Can't have a locale with just a variant -- the variant must accompany a
	 * valid language or country code). Examples: "en", "de_DE", "_GB",
	 * "en_US_WIN", "de__POSIX", "fr__MAC"
	 * 
	 * @param locale
	 *            string representing a locale
	 * @return true if the locale is a valid locale, false if the locale is not
	 *         valid.
	 */
	public static boolean isValidLocale(String locale) {
		return true;
	}

	/**
	 * Reports if a string is blank. A string is considered blank either if it
	 * is null, is an empty string, of consists entirely of white space.
	 * <p>
	 * For example,
	 * <ul>
	 * <li>null, "" and " " are blank strings
	 * </ul>
	 * 
	 * @param str
	 *            the string to check
	 * @return true if the string is blank, false otherwise.
	 */
	public static boolean isBlank(String str) {
		return trimString(str) == null;
	}

	/**
	 * Reports if a string is empty. A string is considered empty either if it
	 * is null, is an empty string.
	 * <p>
	 * For example,
	 * <ul>
	 * <li>Both null and "" are empty strings
	 * <li>" " is not empty string.
	 * </ul>
	 * 
	 * @param value
	 *            the string to check
	 * @return true if the string is empty, false otherwise.
	 */
	public static boolean isEmpty(String value) {
		if (value == null || value.length() == 0)
			return true;
		return false;
	}

	/**
	 * Returns if the two string are null or equal. 
	 * 
	 * @param str1
	 *            the string to compare
	 * @param str2
	 *            the string to compare
	 * @return true, if the two string are null, or the two string are equal
	 *         with case sensitive.
	 */
	public static boolean isEqual(String str1, String str2) {
		return str1 == str2 || (str1 != null && str1.equals(str2));
	}

	/**
	 * Returns if the two string are null or equal. The
	 * {@link java.lang.String#equalsIgnoreCase(String)}is used to compare two
	 * strings.
	 * 
	 * @param str1
	 *            the string to compare
	 * @param str2
	 *            the string to compare
	 * @return true, if the two string are null, or the two string are equal
	 *         with case sensitive.
	 */
	public static boolean isEqualIgnoreCase(String str1, String str2) {
		return str1 == str2 || (str1 != null && str1.equalsIgnoreCase(str2));
	}

	/**
	 * Extract file name (without path and suffix) from file name with path and
	 * suffix.
	 * <p>
	 * For example:
	 * <p>
	 * <ul>
	 * <li>"c:\home\abc.xml" => "abc"
	 * <li>"c:\home\abc" => "abc"
	 * <li>"/home/user/abc.xml" => "abc"
	 * <li>"/home/user/abc" => "abc"
	 * </ul>
	 * 
	 * @param filePathName
	 *            the file name with path and suffix
	 * @return the file name without path and suffix
	 */
	public static String extractFileName(String filePathName) {
		if (filePathName == null)
			return null;

		int dotPos = filePathName.lastIndexOf('.');
		int slashPos = filePathName.lastIndexOf('\\');

		int backSlashPos = filePathName.lastIndexOf('/');
		slashPos = slashPos > backSlashPos ? slashPos : backSlashPos;

		if (dotPos > slashPos) {
			return filePathName.substring(slashPos > 0 ? slashPos + 1 : 0,
					dotPos);
		}

		return filePathName.substring(slashPos > 0 ? slashPos + 1 : 0);
	}

	/**
	 * Extract file name (without path but with suffix) from file name with path
	 * and suffix.
	 * <p>
	 * For example:
	 * <p>
	 * <ul>
	 * <li>"c:\home\abc.xml" => "abc.xml"
	 * <li>"c:\home\abc" => "abc"
	 * <li>"/home/user/abc.xml" => "abc.xml"
	 * <li>"/home/user/abc" => "abc"
	 * </ul>
	 * 
	 * @param filePathName
	 *            the file name with path and suffix
	 * @return the file name without path but with suffix
	 */
	public static String extractFileNameWithSuffix(String filePathName) {
		if (filePathName == null)
			return null;

		int slashPos = filePathName.lastIndexOf('\\');
		int backSlashPos = filePathName.lastIndexOf('/');

		slashPos = slashPos > backSlashPos ? slashPos : backSlashPos;
		return filePathName.substring(slashPos > 0 ? slashPos + 1 : 0);
	}

	/**
	 * Extracts the libaray namespace from the given qualified reference value.
	 * <p>
	 * For example,
	 * <ul>
	 * <li>"LibA" is extracted from "LibA.style1"
	 * <li>null is returned from "style1"
	 * </ul>
	 * 
	 * @param qualifiedName
	 *            the qualified reference value
	 * @return the library namespace
	 */
	public static String extractNamespace(String qualifiedName) {
		if (qualifiedName == null)
			return null;

		int pos = qualifiedName.lastIndexOf('.');
		if (pos == -1)
			return null;

		return StringUtils.trimString(qualifiedName.substring(0, pos));
	}

	/**
	 * Extracts the name from the given qualified reference value.
	 * 
	 * <p>
	 * For example,
	 * <ul>
	 * <li>"style1" is extracted from "LibA.style1"
	 * <li>"style1" is returned from "style1"
	 * </ul>
	 * 
	 * @param qualifiedName
	 *            the qualified reference value
	 * @return the name
	 */
	public static String extractName(String qualifiedName) {
		if (qualifiedName == null)
			return null;
		int pos = qualifiedName.lastIndexOf('.');
		if (pos == -1)
			return qualifiedName;

		return StringUtils.trimString(qualifiedName.substring(pos + 1));
	}

	/**
	 * Builds the qualified reference value.
	 * <p>
	 * For example,
	 * <ul>
	 * <li>("LibA", "style1") => "LibA.style1"
	 * <li>(" ", "style1) => "style1"
	 * </ul>
	 * 
	 * @param namespace
	 *            the library namespace to indicate which library the reference
	 *            is using.
	 * @param value
	 *            the actual reference value
	 * @return the qualified reference value
	 */
	public static String buildQualifiedReference(String namespace, String value) {
		if (StringUtils.isBlank(namespace))
			return value;

		return namespace + "." + value; //$NON-NLS-1$
	}

	/**
	 * Trims the quotes.
	 * <p>
	 * For example,
	 * <ul>
	 * <li>("a.b") => a.b
	 * <li>("a.b) => "a.b
	 * <li>(a.b") => a.b"
	 * </ul>
	 * 
	 * @param value
	 *            the string may have quotes
	 * @return the string without quotes
	 */
	public static String trimQuotes(String value) {
		if (value == null)
			return value;

		value = value.trim();
		if (value.startsWith("\"") && value.endsWith("\"")) 
			return value.substring(1, value.length() - 1);
		if (value.startsWith("'") && value.endsWith("'")) 
			return value.substring(1, value.length() - 1);

		return value;
	}
	
	 /**
	  * 根据指定文本中给定参数符号，将参数符号替换成相应的参数值
	  * @param dpSymbol
	  * @param dpText
	  * @param dpValues
	  * @return String
	  */
	public static String replaceDynamicParameters(String dpSymbol, String dpText, Object[] dpValues) {
		if (dpText == null || dpText.equals("")) return dpText;
		for (int i = 0; i <= dpValues.length - 1; i++) {
			dpText = dpText.replaceFirst(dpSymbol, String.valueOf(dpValues[i]));
		}
		return dpText;
	}
	
	/**
	 * 提供一种默认的参数替换规则,将#号动态替换成相应的参数值
	 * @param dpText
	 * @param dpValues
	 * @return String
	 */
	public static String replaceDynamicParameters(String dpText, Object[] dpValues) {
		if (dpText == null || dpText.equals("")) return dpText;
		for (int i = 0; i <= dpValues.length - 1; i++) {
			dpText = dpText.replaceFirst("#", String.valueOf(dpValues[i]));
		}
		return dpText;
	}

	/**
	 * 提供字符分隔规则,将数组对象换成相应字符分隔的字符串值
	 * @param dpSymbol
	 * @param dpValues
	 * @return String
	 */
	public static String toString(String dpSymbol, Object[] dpValues) {
		if (dpSymbol == null || dpSymbol.equals("")) dpSymbol = ",";
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i <= dpValues.length - 1; i++) {
			sb.append("\"").append(dpValues[i]).append("\"");
			if (i < dpValues.length - 1) sb.append(dpSymbol);
		}
		return sb.toString();
	}
	
	/**
	 * 提取字符串中含有的数字
	 * 
	 * @param stringNum
	 * @return int
	 */
	public static int getStringNumber(String stringNum) {
        String str = null;
        int num = 0;
        if (stringNum != null) {
            for (int i = 0; i < stringNum.length(); i++) { 
                 char c = stringNum.charAt(i); 
                 if (c >= '0' && c <= '9' || c == '.') {
                     if (str != null) {
                         str = str + Character.toString(c);
                     } else {
                         str = Character.toString(c);
                     }
                 }
            }
            if (str != null) num = Integer.parseInt(str);
        }
        return num;    
    }
	
	/**
	 * 判断指定文件名的扩展名是不是图片类型(注：扩展名限定为gif、jpg、jpeg和png)
	 */
	public static boolean isPicture(String ext) {
		if (ext == null || ext.trim().equals("")) 
			return false;
		if (ext.equalsIgnoreCase("gif"))  return true;
		if (ext.equalsIgnoreCase("jpeg")) return true;
		if (ext.equalsIgnoreCase("jpg"))  return true;
		if (ext.equalsIgnoreCase("png"))  return true;
		return false;	
	}
	
	public static boolean isMedia(String ext) {
		if (ext == null || ext.trim().equals("")) 
			return false;
		if (ext.equalsIgnoreCase("swf"))  return true;
		if (ext.equalsIgnoreCase("flv")) return true;
		if (ext.equalsIgnoreCase("avi"))  return true;
		if (ext.equalsIgnoreCase("mp3"))  return true;
		if (ext.equalsIgnoreCase("mp3"))  return true;		
		return false;	
	}
	
	public static boolean isJsFile(String ext){
		if (ext == null || ext.trim().equals("")) 
			return false;
		if (ext.equalsIgnoreCase("js"))  return true;
		return false;	
	}
	
	public static boolean isCssFile(String ext){
		if (ext == null || ext.trim().equals("")) 
			return false;
		if (ext.equalsIgnoreCase("css"))  return true;
		return false;	
	}
	
	/**
	 * 判断一个空对象为null或size为0，创建list对象
	 */
	public static List<?> vailList(List<?> varList) {
		if (varList == null||varList.size() == 0) {
			return new ArrayList<Object>();
		}
		return varList; 
	}
	
	/**
	 * 根据参数转换日期格式：yyyy/MM/dd HH:mm:ss
	 */
	public static String toFormatDate(String format, Date date) {
		String newDateStr = "";		
		if (format == null || format.equals("")) {
			format = "yyyy/MM/dd HH:mm:ss";
		}
		if (date != null) {
			SimpleDateFormat dateFormat = new SimpleDateFormat(format);
			newDateStr = dateFormat.format(date);
		}
 		return newDateStr;
 	}
	
	
	/**
	 * 获取正则时间
	 * @param Date
	 * @return String
	 */
	public static String getRegularTime(Date date) {
		if (date == null) return null;
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		StringBuffer sb = new StringBuffer();
		sb.append(c.get(Calendar.SECOND)).append(" ");
		sb.append(c.get(Calendar.MINUTE)).append(" ");
		sb.append(c.get(Calendar.HOUR_OF_DAY)).append(" ");
		sb.append(c.get(Calendar.DAY_OF_MONTH)).append(" ");
		sb.append(c.get(Calendar.MONTH) + 1).append(" ");				
		sb.append("? ").append(c.get(Calendar.YEAR));
		return sb.toString();
	}
	
	/**
	 * 获取客户端有效的IP地址
	 * @param request
	 * @return String
	 */
	public static String getIpAddr(HttpServletRequest request) {     
	     String ip = request.getHeader("x-forwarded-for");   
	     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
	         ip = request.getHeader("Proxy-Client-IP");     
	     }     
	      if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
	         ip = request.getHeader("WL-Proxy-Client-IP");    
	     }     
	     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {     
	    	 ip = request.getRemoteAddr();     
	     }     
	     return ip;     
	}  
	
	/**
	 * 获取消息MD5摘要值
	 * @param message
	 * @return String
	 */
    public static String getDigest(byte[] message) {
    	StringBuffer hexValue = new StringBuffer();
    	try {
    		if (message != null && message.length > 0) {
		    	MessageDigest md = MessageDigest.getInstance("MD5");
		        byte[] mdBytes = md.digest(message);
		        for (int i = 0; i < mdBytes.length; i++) {
		            int val = ((int) mdBytes[i]) & 0xff;
		            if (val < 16) {
		                hexValue.append("0");
		            }
		            hexValue.append(Integer.toHexString(val));
		        }
    		}
    	} catch (Exception ex) {}
    	return hexValue.toString();
    }
    
    /**
     * 网页中input输入的字符串可能有&,<,>,',"等，此处替换为转义字符，以免引起网页渲染错误
     * @param strData
     * @return
     */
    public static String htmlEscape(String strData)
    {
        if (strData == null)
        {
            return "";
        }
        strData = replaceString(strData, "&", "&amp;");
        strData = replaceString(strData, "<", "&lt;");
        strData = replaceString(strData, ">", "&gt;");
        strData = replaceString(strData, "'", "&apos;");
        strData = replaceString(strData, "\"", "&quot;");
        return strData;
    }
    
    
    /**
     * 替换字符串方法
     * @param strData
     * @param regex
     * @param replacement
     * @return
     */
    public static String replaceString(String strData, String regex, String replacement)
    {
        if (strData == null)
        {
            return null;
        }
        int index;
        index = strData.indexOf(regex);
        String strNew = "";
        if (index >= 0)
        {
            while (index >= 0)
            {
                strNew += strData.substring(0, index) + replacement;
                strData = strData.substring(index + regex.length());
                index = strData.indexOf(regex);
            }
            strNew += strData;
            return strNew;
        }
        return strData;
    }
	
}